package org.linlinjava.litemall.wx.service;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import org.linlinjava.litemall.core.task.TaskService;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.dao.LitemallRentNotReturnMapper;
import org.linlinjava.litemall.db.domain.LitemallGoodsProduct;
import org.linlinjava.litemall.db.domain.LitemallRentNotReturn;
import org.linlinjava.litemall.db.domain.LitemallRentNotReturnDetail;
import org.linlinjava.litemall.db.domain.LitemallRentOrderDetail;
import org.linlinjava.litemall.db.service.LitemallGoodsProductService;
import org.linlinjava.litemall.db.service.LitemallRentNotReturnService;
import org.linlinjava.litemall.db.service.LitemallRentOrderDetailService;
import org.linlinjava.litemall.db.util.PayStatusConstant;
import org.linlinjava.litemall.db.util.RentNotReturnConstant;
import org.linlinjava.litemall.wx.dto.GoodsProductSimpleDto;
import org.linlinjava.litemall.wx.dto.PayInfo;
import org.linlinjava.litemall.wx.dto.RentNotReturnDto;
import org.linlinjava.litemall.wx.task.MemberOrderUnpaidTask;
import org.linlinjava.litemall.wx.task.OrderUnpaidTask;
import org.linlinjava.litemall.wx.task.RentNotReturnOrderUnpaidTask;
import org.linlinjava.litemall.wx.util.IDHelper;
import org.linlinjava.litemall.wx.util.SnUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author Administrator
 */
@Service("notReturn-pay")
public class WxRentNotReturnService implements PayProcessor{
    @Resource
    private LitemallRentNotReturnService rentNotReturnService;
    @Autowired
    private LitemallGoodsProductService goodsProductService;
    @Autowired
    private LitemallRentOrderDetailService rentOrderDetailService;
    @Resource
    private LitemallRentNotReturnMapper rentNotReturnMapper;
    @Autowired
    private TaskService taskService;
    public Object detail(Integer userId,Integer rentOrderId){
     return null;
    }

    @Transactional(rollbackFor = Exception.class)
    public Object submit(Integer userId, RentNotReturnDto rentNotReturnDto) {
        if (userId ==null) {
            return ResponseUtil.unlogin();
        }
        GoodsProductSimpleDto[] goodsProductSimpleDtos = rentNotReturnDto.getGoodsProductSimpleDtos();

        BigDecimal totalFee = BigDecimal.ZERO;
        for (GoodsProductSimpleDto goodsProductSimpleDto : goodsProductSimpleDtos) {
            LitemallGoodsProduct goodsProduct = goodsProductService.findById(goodsProductSimpleDto.getGoodsProductId());
            LitemallRentOrderDetail rentOrderDetail = rentOrderDetailService.queryByUidAndGoodsProductId(userId, goodsProduct.getId());
            Integer originalNumber = rentOrderDetail.getNumber();
            if (originalNumber > goodsProductSimpleDto.getNumber()) {
                rentOrderDetail.setNumber(originalNumber - goodsProductSimpleDto.getNumber());
                LitemallRentOrderDetail rentOrderDetail1 = new LitemallRentOrderDetail();
                rentOrderDetail1.setUserId(userId);
                rentOrderDetail1.setGoodsId(rentOrderDetail.getGoodsId());
                rentOrderDetail1.setGoodsProductId(rentOrderDetail.getGoodsProductId());
                rentOrderDetail1.setName(rentOrderDetail.getName());
            }
            rentOrderDetail.setNumber(goodsProductSimpleDto.getNumber());
            rentOrderDetail.setStatus(RentNotReturnConstant.STATUS_WAITING);
            BigDecimal price = goodsProduct.getPrice().multiply(BigDecimal.valueOf(goodsProductSimpleDto.getNumber()));
            totalFee = totalFee.add(price);
        }
        BigDecimal finalFee = totalFee.multiply(new BigDecimal("0.5"));

        /* 更新不想还书表 */
        LitemallRentNotReturn rentNotReturn = new LitemallRentNotReturn();
        rentNotReturn.setTotalPrice(finalFee);
        rentNotReturn.setUserId(userId);
        rentNotReturn.setOrderSn(SnUtil.generateOrderSn(SnUtil.generateOrderSn()));

        rentNotReturnMapper.insertSelective(rentNotReturn);
        // 订单支付超期任务
        taskService.addTask(new OrderUnpaidTask(rentNotReturn.getId()));

        /* 更新不想还书详情表 */
        for (GoodsProductSimpleDto goodsProductSimpleDto : goodsProductSimpleDtos) {
            LitemallGoodsProduct goodsProduct = goodsProductService.findById(goodsProductSimpleDto.getGoodsProductId());
            LitemallRentNotReturnDetail rentNotReturnDetail = new LitemallRentNotReturnDetail();
            rentNotReturnDetail.setGoodsProductId(goodsProduct.getId());
            rentNotReturnDetail.setGoodsId(goodsProduct.getGoodsId());
            rentNotReturnDetail.setNumber(goodsProductSimpleDto.getNumber());
            rentNotReturnDetail.setNotReturnId(rentNotReturn.getId());
            rentNotReturnDetail.setAddTime(LocalDateTime.now());
        }
        Integer orderId = rentNotReturn.getId();
        Map<String, Object> data = new HashMap<>();
        data.put("finalFee",finalFee);
        data.put("orderId", orderId);
        return ResponseUtil.ok(data);
    }

    public Object checkOut(Integer userId,RentNotReturnDto rentNotReturnDto) {
        GoodsProductSimpleDto[] goodsProductSimpleDtos = rentNotReturnDto.getGoodsProductSimpleDtos();

        BigDecimal totalFee = BigDecimal.ZERO;
        List<LitemallGoodsProduct> goodsProductList = new ArrayList<>();
        for (GoodsProductSimpleDto goodsProductSimpleDto : goodsProductSimpleDtos) {
            LitemallGoodsProduct goodsProduct = goodsProductService.findById(goodsProductSimpleDto.getGoodsProductId());
            goodsProductList.add(goodsProduct);
            BigDecimal price = goodsProduct.getPrice().multiply(BigDecimal.valueOf(goodsProductSimpleDto.getNumber()));
            totalFee = totalFee.add(price);
        }
        Map<String, Object> data = new HashMap<>();
        data.put("goodsProductList",goodsProductList);
        data.put("totolFee",totalFee);
        return data;
    }

    @Override
    public PayInfo checkPayInfo(Integer userId, Integer id) {
        LitemallRentNotReturn rentNotReturn = rentNotReturnService.findById(id);
        if (rentNotReturn == null) {
            return null;
        }
        if (!rentNotReturn.getUserId().equals(userId)) {
            return null;
        }
        PayInfo payInfo = new PayInfo();
        payInfo.setOrderSn(rentNotReturn.getOrderSn());
        payInfo.setPrice(rentNotReturn.getTotalPrice());
        return payInfo;
    }

    @Override
    public Object recordSuccess(String orderSn) {
        return recordSuccess(orderSn,null,null);
    }

    @Override
    public Object recordSuccess(String orderSn, String totalFee, String payId) {
        LitemallRentNotReturn rentNotReturn = rentNotReturnService.findBySn(orderSn);
        if (rentNotReturn == null) {
            return WxPayNotifyResponse.fail("订单不存在 sn=" + orderSn);
        }

        if (totalFee == null) {
            totalFee = rentNotReturn.getTotalPrice().toString();
        }

        rentNotReturn.setPayId(payId);
        rentNotReturn.setPayTime(LocalDateTime.now());
        rentNotReturn.setStatus(PayStatusConstant.HAS_PAID);

        Integer rentOrderId = rentNotReturn.getRentOrderId();

        List<LitemallRentOrderDetail> rentOrderDetailList = rentOrderDetailService.queryWaitByOid(rentOrderId);
        for (LitemallRentOrderDetail rentOrderDetail : rentOrderDetailList) {
            rentOrderDetail.setStatus(RentNotReturnConstant.STATUS_PAID);
            rentOrderDetailService.updateById(rentOrderDetail);
        }


        return WxPayNotifyResponse.success("处理成功!");
    }


}
